package cz.acies.genea.ui.chart;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.commons.lang3.time.DateFormatUtils;

import cz.acies.data.DBConnector;
import cz.acies.genea.data.dao.GedFamilyDAO;
import cz.acies.genea.data.dao.GedPersonDAO;
import cz.acies.genea.data.persist.GedFamily;
import cz.acies.genea.data.persist.GedPerson;
import cz.acies.genea.data.persist.GedProject;

public class TreeChart0
{
	public static void main(String[] args) {
		try {
			/*
			// HOME
			String jdbcUrl = "jdbc:mysql://localhost:3306/gedcom";
			String jdbcDriver = "org.gjt.mm.mysql.Driver";
			
			Properties props = new Properties();
			props.setProperty("user", "root");
			props.setProperty("password", "smart");
			props.setProperty("useUnicode", "true");
			props.setProperty("characterEncoding", "UTF8");
			props.setProperty("characterSetResults", "UTF8");
			*/
			// WORK
			String jdbcUrl = "jdbc:mysql://localhost:3305/gedcom";
			String jdbcDriver = "org.gjt.mm.mysql.Driver";

			Properties props = new Properties();
			props.setProperty("user", "root");
			props.setProperty("password", "");
			props.setProperty("useUnicode", "true");
			props.setProperty("characterEncoding", "UTF8");
			props.setProperty("characterSetResults", "UTF8");
			
			String dialectClass = "cz.acies.uniql.dialect.MySQLDialect"; 
			
			DBConnector connector = DBConnector.instance();
			connector.setUrl(jdbcUrl);
			connector.setDriver(jdbcDriver);
			connector.setDialectClass(dialectClass);
			connector.setProps(props);
			connector.initialize();
			
			TreeChart0 inst = new TreeChart0();
			String html = inst.build();
			System.out.println(html);
			
		} catch (Exception exc) {
			exc.printStackTrace();
		}
	}

	private String rootId = "";
	private long maxBirthDay = 0;
	private String maxPersonId = "";
	
	private GedProject project = null;
	
	private Map<String, GedFamily> fReg = null; 	// index rodin
	private Map<String, GedPerson> pReg = null;		// index osob
	
	private Map<Integer, List<GedPerson>> rows = null;	// model generací
	private Map<String, Integer> genPReg = null;	// index osob v řádcích modelu generací
	
	
	public TreeChart0() {}
	
	public String build() throws Exception {
		String html = "";
		createModel();
		/*
		// WORK
		maxPersonId = "GE.R.2Z2V4UEAG6KD9B1"; 	//já
		maxPersonId = "GE.R.2P4MZ98NZSAN0SP"; 		//táta
		maxPersonId = "GE.R.8Y25KHJH3W5CJCS";		//máma
		maxPersonId = "GE.R.HJ97H0M5RO7WW4O";		//deda burian
		maxPersonId = "GE.R.HJ97H0M5RO7WW4O";		//deda burian
		*/
		// HOME
		maxPersonId = "GE.R.9ZGDO4RZJU6WVKM"; 	//já
		maxPersonId = "GE.R.1ZI4Q5R7BDJW0W6"; 	//táta
		
		GedPerson person = pReg.get(maxPersonId); 
		int row = 0;
		html = buildRow(person, row);
		return html;
	}
	
	private String buildRow(GedPerson person, int row) {
		String html = ""+
		"<table border=\"1\">"+
		"<tr>";
		Map<String, GedFamily> partners = person.getPartners();
		//System.out.println("partners: " + partners);
		if (partners.isEmpty()) {
			String gender = person.getGender();
			if (gender.equals("M")) {
				GedFamily family = new GedFamily(person, null);
				html = createFamilyNode(family);
			} else {
				GedFamily family = new GedFamily(null, person);
				html = createFamilyNode(family);
			}
		} else {
			int i = 0;
			for (Map.Entry<String, GedFamily> e : partners.entrySet()) {
				GedFamily family = e.getValue();
				if (i > 0) {
					try {
						family = (GedFamily) family.clone();
						family.setMan(null); 
					} catch (Exception exc) {
						exc.printStackTrace();
					}
				}
				html += createFamilyNode(family);
				i++;
			}
		}
		html +=
		"</tr>"+
		"</table>";
		return html;
	}
	
	public String createFamilyNode(GedFamily family) {
		String cn = ""; 
		if (family.getChildren() != null && !family.getChildren().isEmpty()) {
			/*
			for (GedPerson child : family.getChildren()) {
				String id = child.getId();
				child = pReg.get(id);
				if (child.getPartners().isEmpty()) {
					GedFamily partners = new GedFamily();
					if (child.getGender().equals("M")) {
						partners.setMan(child);
						partners.setWoman(null);
					} else {
						partners.setMan(null);
						partners.setWoman(child);
					}
					cn += "<td>"+createFamilyNode(partners)+"</td>";
				} else {
					for (Map.Entry<String, GedFamily> e : child.getPartners().entrySet()) {
						GedFamily partners = e.getValue();
						cn += "<td>"+createFamilyNode(partners)+"</td>";
					}
				}
			}
			*/
		}
		String html = ""+
		"<td style=\"vertical-align: top;\">"+
		"<div style=\"text-align: center;\">"+
		"<table border=\"1\">"+
			"<tr>"+
				"<td id=\""+family.getId()+"\">"+
					createFamilyCell(family)+
				"</td>"+
			"</tr>"+
			"<tr>"+
				"<td>"+
					"<div style=\"text-align: center;\">"+
					"<table border=\"1\">"+
						"<tr>"+cn+"</tr>"+
					"</table>"+
					"</div>"+
				"</td>"+
			"</tr>"+
		"</table>"+
		"</div>"+
		"</td>";
		return html;
	}
	
	public String createFamilyCell(GedFamily family) {
		GedPerson man = null;
		GedPerson woman = null;
		if (family != null) {
			man = (family.hasMan()) ? family.getMan() : null;
			woman = (family.hasWoman()) ? family.getWoman() : null;
		}
		String join = "";
		if (!family.getChildren().isEmpty()) {
			join = "-T-";
		}
		String html = ""+
		"<div style=\"text-align: center;\">"+
		"<table style=\"border: 1px;\">"+
			"<tbody>"+
				"<tr>"+
					"<td>"+createPersonCell(man)+"</td>"+
					"<td>"+join+"</td>"+
					"<td>"+createPersonCell(woman)+"</td>"+
				"</tr>"+
			"</tbody>"+
		"</table>"+
		"</div>"+
		"";
		return html;
	}
	
	public String createPersonCell(GedPerson person) {
		String html = "";

		String firstName = "";
		String lastName = "";
		String maidenName = "";

		String birthDate = "";
		String deathDate = "";
		String gender = "";

		if (person != null) {
			gender = (person.hasGender() && person.getGender().toLowerCase().equals("f")) ? "f" : "m";
			firstName = (person.hasFirstName()) ? person.getFirstName() : "";
			lastName = (person.hasLastName()) ? person.getLastName() : "";
			maidenName = (person.hasMaidenName()) ? person.getMaidenName() : "";

			Date now = new Date();

			if (person.getBirthDate() instanceof Date && person.getBirthDate().compareTo(now) < 0) {
				birthDate = "" + DateFormatUtils.format(person.getBirthDate(), "d.M.yyyy");
			}
			if (person.getDeathDate() instanceof Date && person.getDeathDate().compareTo(now) < 0) {
				deathDate = "" + DateFormatUtils.format(person.getDeathDate(), "d.M.yyyy");
			}
			html = 
			"<div style=\"border: 1px solid #ccc; height: 65px; width: 150px;\">"+
			"<table>"+
				"<tr>"+
					"<td>"+
						"<img style=\"width: 20px; height: 20px; margin-right: 5px;\" alt=\"\" "+
							"src=\"/genea/res/icons/empty_photo_"+gender+".PNG\">"+
					"</td>"+
					"<td>"+
						"<table>"+
							"<tr style=\"padding: 2px;\">"+
								"<td>"+
									firstName+" " + lastName + " " +
									((!maidenName.equals(lastName)) ? "(roz."+maidenName+")" : "") +
								"</td>"+
							"</tr>"+
							"<tr>"+
								"<td>*&nbsp;" + birthDate + "</td>"+
							"</tr>"+
							"<tr>"+
								"<td>" + ((deathDate.length() > 0) ? "+&nbsp;"+deathDate : deathDate) + "</td>"+
			                "</tr>"+
			            "</table>"+
			        "</td>"+
			    "</tr>"+
			"</table>" +
			"</div>";
		} else {
			html =
			"<div style=\"border: 1px solid #ccc; height: 65px; width: 20px;\">"+
			"<table>"+
			    "<tr>"+ 
			        "<td>"+
			        "</td>"+
			    "</tr>"+
			"</table>"+
			"</div>";
		}
		return html;
	}
	
	private GedPersonDAO pDao = new GedPersonDAO();
	private GedFamilyDAO fDao = new GedFamilyDAO();
	
	public void createModel() throws Exception {
		
		fReg = new LinkedHashMap<String, GedFamily>();
		pReg = new LinkedHashMap<String, GedPerson>();
		project = new GedProject("", new LinkedHashMap<String, Object>());
		
		List<GedPerson> people = pDao.selectAll();
		project.setPeople(people);
		List<GedFamily> families = fDao.selectAll();
		project.setFamilies(families);
		for (GedFamily family : families) {
			GedPerson man = family.getMan();    
			if (man != null && man.hasId() && !pReg.containsKey(man.getId())) {
				String id = man.getId();
				if (!pReg.containsKey(id)) {
					man = pDao.selectById(id);
					man = initPesson(man);
					family.setMan(man);
					pReg.put(id, man);
				}
			}
			
			GedPerson woman = family.getWoman(); 
			if (woman != null && woman.hasId() && !pReg.containsKey(woman.getId())) {
				String id = woman.getId();
				if (!pReg.containsKey(id)) {
					woman = pDao.selectById(id);
					woman = initPesson(woman);
					family.setWoman(woman);
					pReg.put(id, woman);
				}
			}
			/*
			List<GedPerson> list = fDao.selectChildern(family);
			family.setChildren(list);
			for (GedPerson child : list) {
				child = initPesson(child);
			}
			*/
			fReg.put(family.getId(), family);
		}
		/*
		for (GedPerson person : people) {
			String personId = (person.hasId()) ? person.getId() : "";
			if (pReg.containsKey(personId)) { person = pReg.get(personId); }
			GedFamily parents = person.getParents();
			if (parents != null && parents.hasId()) {
				String parentsId = parents.getId();
				if (person.hasFather()) {
					GedPerson father = person.getFather();
					if (father.hasId()) father = pDao.selectById(father.getId());
				}
				if (person.hasMather()) {
					GedPerson mother = person.getMather();
					if (mother.hasId()) mother = pDao.selectById(mother.getId()); 
				}
				fReg.put(parentsId, parents);
			}
			List<GedPerson> partners = pDao.selectPartnersById(person);
			for (GedPerson partner : partners) {
				String id = (partner.hasId() ) ? ""+partner.getId() : "";
				partner = pDao.selectById(id); 
				GedFamily family = pDao.selectFamily(person, partner);
				String familyId = family.getId(); 
				if (fReg.containsKey(familyId)) {
					person.addPartner(fReg.get(familyId));
				}
			}
			List<GedPerson> childern = pDao.selectChildernById(personId);
			for (GedPerson child : childern) {
				String id = child.getId();
				if (!pReg.containsKey(id)) {
					GedPerson p = pDao.selectById(id);
					person.addChild(p);
					pReg.put(id, p);
				} else {
					GedPerson p = pReg.get(id);
					person.addChild(p);
				}
			}
			person.setChildern(childern);
			pReg.put(personId, person);
		}
		*/
	}

	public GedPerson initPesson(GedPerson person) throws Exception {
		String personId = person.getId();
		GedFamily parents = person.getParents();
		if (parents != null && parents.hasId()) {
			String parentsId = parents.getId();
			if (person.hasFather()) {
				GedPerson father = person.getFather();
				if (father.hasId()) father = pDao.selectById(father.getId());
			}
			if (person.hasMather()) {
				GedPerson mother = person.getMather();
				if (mother.hasId()) mother = pDao.selectById(mother.getId()); 
			}
			//fReg.put(parentsId, parents);
		}
		List<GedPerson> partners = pDao.selectPartners(person);
		for (GedPerson partner : partners) {
			String id = (partner.hasId() ) ? ""+partner.getId() : "";
			partner = pDao.selectById(id); 
			GedFamily family = pDao.selectFamily(person, partner);
			String familyId = family.getId(); 
			/*
			if (fReg.containsKey(familyId)) {
				person.addPartner(fReg.get(familyId));
			}
			*/
		}
		List<GedPerson> childern = pDao.selectChildernById(personId);
		for (GedPerson child : childern) {
			String id = child.getId();
			if (!pReg.containsKey(id)) {
				GedPerson p = pDao.selectById(id);
				person.addChild(p);
				pReg.put(id, p);
			} else {
				GedPerson p = pReg.get(id);
				person.addChild(p);
			}
		}
		person.setChildern(childern);
		return person;
	}
	
	protected int findInGeneration(GedPerson person) {
		return 0;
	}
}
